package sg.edu.nus.comp.icreate.ivletalk;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import sg.edu.nus.comp.icreate.ivletalk.events.DisplayEvents;
import sg.edu.nus.comp.icreate.ivletalk.module.MainActivity;
import sg.edu.nus.comp.icreate.ivletalk.voice.VoiceCommand;
import sg.edu.nus.comp.icreate.ivletalk.voice.VoiceCommandManager;
import sg.edu.nus.comp.icreate.ivletalk.voice.WebPageUrl;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.net.Uri;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ListView;

public abstract class BaseActivity extends Activity implements OnInitListener {
	public static final int REQUEST_CODE_SPEECH = 1234;
	public static final String EXTRA_NEED_REFRESH = "needRefresh";
	private final Context context = this;
	protected static final int ICON_TEXT_PADDING = 10;
	private TextToSpeech mText2Speech;
	private MediaPlayer mediaPlayer;
	static private AlertDialog alert;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
		mediaPlayer = new MediaPlayer();
		mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
		mText2Speech = new TextToSpeech(this, this);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.actionModule:
			return handleActionModule();
		case R.id.actionLogout:
			return handleActionLogout();
		case R.id.actionEvent:
			return handleActionEvent();
		case R.id.actionRefresh:
			return handleActionRefresh();
		case R.id.actionSpeech:
			return handleActionSpeech();
		case R.id.actionHelp:
			return handleActionHelp();
		default:
			return true;
		}
	}

	public boolean executeMenuVoiceCommand(String cmd) {
		if (cmd.equals(VoiceCommand.REFRESH.getPattern())) {
			return handleActionRefresh();
		} else if (cmd.equals(VoiceCommand.LOGOUT.getPattern())) {
			return handleActionLogout();
		} else if (cmd.equals(VoiceCommand.EVENTS.getPattern())) {
			return handleActionEvent();
		} else if (cmd.equals(VoiceCommand.HELP.getPattern())) {
			return handleActionHelp();
		} else if (cmd.equals(VoiceCommand.MODULES.getPattern())) {
			return handleActionModule();
		} else if (cmd.equals(VoiceCommand.SING_A_SONG.getPattern())) {
			return handleActionSingASong();
		} else {
			return false;
		}
	}

	private boolean handleActionHelp() {
		Intent intent = new Intent(getApplicationContext(), HelpActivity.class);
		startActivity(intent);
		return true;
	}

	private boolean handleActionSingASong() {
		try {
			mediaPlayer.setDataSource(getApplicationContext(), Uri.parse(WebPageUrl.SONG.getUrl()));
			mediaPlayer.prepare();
			mediaPlayer.start();
			mediaPlayer.setOnCompletionListener(new OnCompletionListener() {
				@Override
				public void onCompletion(MediaPlayer mp) {
					alert.cancel();
				}
			});
			stopSongAlertDialog();
			return true;
		} catch (Exception e) {
			return false;
		}

	}

	public boolean handleActionSpeech() {
		Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
		intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
		intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "Voice Recognition...");
		startActivityForResult(intent, REQUEST_CODE_SPEECH);
		return true;
	}

	protected boolean handleActionLogout() {
		User.clearUserPersistence(this);
		Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
		intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
		intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
		startActivity(intent);
		return true;
	}

	public void speak(String speakText) {
		if(mText2Speech.isSpeaking())
			mText2Speech.speak(speakText, TextToSpeech.QUEUE_ADD, null);
		else
			mText2Speech.speak(speakText, TextToSpeech.QUEUE_FLUSH, null);
		mText2Speech.playSilence(500, TextToSpeech.QUEUE_ADD, null);

	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		VoiceCommandManager commandManager = new VoiceCommandManager();
		if (requestCode == REQUEST_CODE_SPEECH && resultCode == RESULT_OK) {
			ArrayList<String> command = data.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
			if (!commandManager.executeCommand(command, context)) {
				invalidCommandAlert();
			}
		}
		super.onActivityResult(requestCode, resultCode, data);
	}

	public void invalidCommandAlert() {
		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
		alertDialogBuilder.setMessage("Invalid voice command. Try again?").setCancelable(false).setPositiveButton("YES", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
				handleActionSpeech();
			}
		}).setNegativeButton("NO", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
			}
		});
		AlertDialog alertDialog = alertDialogBuilder.create();
		alertDialog.show();
	}

	public void stopVoiceAlertDialog() {
		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
		alertDialogBuilder.setCancelable(false).setPositiveButton("Stop speech", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
				mText2Speech.stop();
				mText2Speech.shutdown();
			}
		});
		AlertDialog alertDialog = alertDialogBuilder.create();
		alertDialog.show();
	}

	public void stopSongAlertDialog() {
		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
		alertDialogBuilder.setCancelable(false).setPositiveButton("Stop", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
				mediaPlayer.stop();
			}
		});
		AlertDialog alertDialog = alertDialogBuilder.create();
		alertDialog.show();
	}

	public void invalidChoiceAlert() {
		AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
		alertDialogBuilder.setMessage("Invalid Choice. Try again?").setCancelable(false).setPositiveButton("YES", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
				handleActionSpeech();
			}
		}).setNegativeButton("NO", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
			}
		});
		AlertDialog alertDialog = alertDialogBuilder.create();
		alertDialog.show();
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
	}

	protected boolean handleActionModule() {
		Intent intent = new Intent(getApplicationContext(), MainActivity.class);
		startActivity(intent);
		return true;
	}

	protected boolean handleActionEvent() {
		Intent intent = new Intent(getApplicationContext(), DisplayEvents.class);
		startActivity(intent);
		return true;
	}

	public void selectNumberedItem(int position) {
		goToItem(position);
	}

	public List<?> getDisplayedItem() {
		return getDisplayedItemList();
	}

	public ArrayList<Object> getItem(int size, ListView list) {
		ArrayList<Object> returnList = new ArrayList<Object>();
		for (int i = 0; i < size; i++) {
			returnList.add(list.getAdapter().getItem(i));
		}

		return returnList;
	}

	public void openWebPage(String url) {
		if (!url.startsWith("http://") && !url.startsWith("https://"))
			url = "http://" + url;
		Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
		startActivity(browserIntent);
	}

	abstract protected List<?> getDisplayedItemList();

	abstract protected void goToItem(int position);

	abstract protected boolean handleActionRefresh();

	public Boolean goNewPost() {
		// do nothing
		return null;
	}

	@Override
	public void onInit(int status) {
		if (status == TextToSpeech.SUCCESS) {
			mText2Speech.setLanguage(Locale.US);
		}
	}

}